import traceback
import logging
from datetime import datetime
from unittest.util import sorted_list_difference

from django.conf import settings
from django.contrib.messages import success
from django.shortcuts import render
from django.utils.text import normalize_newlines
from rest_framework import status, viewsets
from rest_framework.views import APIView
from .models import Card,Order
from rest_framework.response import Response
from utils import common
from ..account.models import Profile
from utils.zhifubao import Alipay
from ..movie.serializers import CategorySerializer
from django.utils import timezone

logger = logging.getLogger('order')

class CardViewSet(viewsets.ModelViewSet):
    queryset = Card.objects.all()
    serializer_class = CategorySerializer


# Create your views here.
class AlipayAPIView(APIView):
    def get(self,request):
        print(timezone.now())

        #获得页面传递的值,none说明如果 URL 中没有 card_id 这个参数，就返回
        card_id=request.GET.get('card_id',None)
        try:
            #取得商品表的信息
            card=Card.objects.get(pk=card_id)
            # 1. 用序列化器转换为字典
            print(card.card_price)
        except:
            error_msg = "404,商品表取值失败" + str(card_id)
            return Response({"error":error_msg}, status=status.HTTP_404_NOT_FOUND)
        #自定义一个订单号
        out_trade_no="pay"+datetime.now().strftime('%Y%m%d%H%M%S')+common.get_random_codes(4)

        #将商品表信息存如订单表中
        try:
            Order.objects.create(
                card_id=card.pk,
                order_sn=out_trade_no,
                order_mount=card.card_price,
                pay_time=timezone.now(),
            )
        except Exception as e:
            # 打印具体错误信息（在控制台/日志中查看）
            # 1. 记录错误信息到日志文件
            logger.error("订单创建失败详情：%s", str(e))  # 记录错误描述
            logger.error("错误栈：%s", traceback.format_exc())  # 记录完整堆栈（关键）

            print("订单创建失败详情：", str(e))
            print("错误栈：", traceback.format_exc())  # 打印完整错误堆栈
            return Response({"error": "405,订单创建失败:"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


        #调用支付接口进行支付
        #对于类中的方法，调用时一定要先实例化，才能调用否则，会缺少self参数
        alipay = Alipay()
        try:
            out_trade_no=out_trade_no
            total_amount=str(card.card_price)
            subject=card.card_name
            body="支付宝支付"
            product_code='FAST_INSTANT_TRADE_PAY'
            pay_url=alipay.trade_page(out_trade_no,total_amount,subject,body,product_code)
            return Response(pay_url)

        except Exception as e:
            # 打印具体错误信息（在控制台/日志中查看）
            # 1. 记录错误信息到日志文件
            logger.error("订单创建失败详情：%s", str(e))  # 记录错误描述
            logger.error("错误栈：%s", traceback.format_exc())  # 记录完整堆栈（关键）

            return Response({"error":"406,支付失败"}, status=status.HTTP_404_NOT_FOUND)

class AlipayCallbackAPIView(APIView):

    def post(self,request):

        #将返回值改成字典
        params=request.POST.dict()
        #去除sign和sign_type字段
        sign = params.pop('sign')
        del params['sign_type']
        # 对字段进行排序
        sorted_list = sorted([(k, v) for k, v in params.items()])
        unsigned_string = '&'.join(f"{k}={v}" for k, v in sorted_list)
        print(unsigned_string)
        alipay = Alipay()
        #支付宝回调验证
        if not alipay.verify_sign(unsigned_string,sign):
            print("407,支付接口回调失败")
            return Response({"error":"407,支付接口回调失败"}, status=status.HTTP_400_BAD_REQUEST)

        #本地数据验证
        #验证订单号
        try:
            order=Order.objects.get(order_sn=params.get('out_trade_no'))
        except:
            print('410')
            return Response({"error":"410"}, status=status.HTTP_404_NOT_FOUND)
        if params.get('total_amount') != str(order.order_mount):
            # print(params.get('total_amount'))
            # print(str(order.order_mount))
            print('411')
            return Response({"error":"411"}, status=status.HTTP_404_NOT_FOUND)
        if params.get('seller_id') != settings.ALIPAY_SELLER_ID:
            print('412')
            return Response({"error":"406,<UNK>"}, status=status.HTTP_404_NOT_FOUND)
        if params.get('app_id') != settings.ALIPAY_APP_ID:
            print('413')
            return Response({"error":"406,<UNK>"}, status=status.HTTP_404_NOT_FOUND)
        if params.get('trade_status') not in ['TRADE_SUCCESS','TRADE_FINISHED']:
            print('414')
            return Response({"error":"406,<UNK>"}, status=status.HTTP_404_NOT_FOUND)

        #全部通过后，执行业务
        #更新order表，order在前面已经实例化过了
        try:
            order.trade_no = params.get('trade_no')
            order.pay_status = params.get('trade_status')
            order.pay_time = timezone.now()
            order.save()
        except Exception as e:
            print(e)
        #跟新用户表
        return Response('success')
